<p>This page tests getting and setting window properties and functions.</p>
<pre id="console"></pre>

<script>
function log(s)
{
    document.getElementById("console").appendChild(document.createTextNode(s + "\n"));
}

function shouldBe(a, b)
{
    var evalA, evalB;
    try {
        evalA = eval(a);
        evalB = eval(b);
    } catch(e) {
        evalA = e;
    }

    var message = (evalA === evalB)
                    ? "PASS: " + a + " should be '" + evalB + "' and is."
                    : "*** FAIL: " + a + " should be '" + evalB + "' but instead is " + evalA + ". ***";
    log(message);
}

function shouldBeTrue(a) 
{ 
    shouldBe(a, "true"); 
}

function shouldBeFalse(b) 
{ 
    shouldBe(b, "false"); 
}

function canGet(keyPath)
{
    try {
        return eval("window." + keyPath) !== undefined;
    } catch(e) {
        return false;
    }
}

window.marker = { "foo": "bar", toString: function(){ return "window.marker.toString()"; } };
window.callableMarker = function() { return "window.callableMarker.toString()"; };

function canSet(keyPath)
{
    var valuePath = "window.marker";

    try {
        eval("window." + keyPath + " = " + valuePath);
        return eval("window." + keyPath) === eval("window." + valuePath);
    } catch(e) {
        return false;
    }
}

function canSetWithTypeConversion(keyPath)
{
    var valuePath = "window.marker";

    try {
        eval("window." + keyPath + " = " + valuePath);
        return eval("window." + keyPath) == eval("window." + valuePath);
    } catch(e) {
        return false;
    }
}

function canSetWithCallable(keyPath)
{
    var valuePath = "window.callableMarker";

    try {
        eval("window." + keyPath + " = " + valuePath);
        return eval("window." + keyPath) === eval("window." + valuePath);
    } catch(e) {
        return false;
    }
}

var windowReadWriteProperties = [
    "Attr", 
    "CDATASection", 
    "CSSRule", 
    "CSSStyleDeclaration", 
    "CharacterData", 
    "Comment", 
    "DOMException", 
    "DOMImplementation", 
    "DOMParser", 
    "Document", 
    "DocumentFragment", 
    "DocumentType", 
    "Element", 
    "EvalError", 
    "Event", 
    "HTMLAnchorElement", 
    "HTMLAreaElement", 
    "HTMLBRElement", 
    "HTMLBaseElement", 
    "HTMLBodyElement", 
    "HTMLButtonElement", 
    "HTMLCanvasElement", 
    "HTMLDListElement", 
    "HTMLDirectoryElement", 
    "HTMLDivElement", 
    "HTMLDocument", 
    "HTMLElement", 
    "HTMLFieldSetElement", 
    "HTMLFontElement", 
    "HTMLFormElement", 
    "HTMLFrameElement", 
    "HTMLFrameSetElement", 
    "HTMLHRElement", 
    "HTMLHeadElement", 
    "HTMLHeadingElement", 
    "HTMLHtmlElement", 
    "HTMLIFrameElement", 
    "HTMLImageElement", 
    "HTMLInputElement", 
    "HTMLIsIndexElement", 
    "HTMLLIElement", 
    "HTMLLabelElement", 
    "HTMLLegendElement", 
    "HTMLLinkElement", 
    "HTMLMapElement", 
    "HTMLMarqueeElement", 
    "HTMLMenuElement", 
    "HTMLMetaElement", 
    "HTMLModElement", 
    "HTMLOListElement", 
    "HTMLOptGroupElement", 
    "HTMLOptionElement", 
    "HTMLParagraphElement", 
    "HTMLParamElement", 
    "HTMLPreElement", 
    "HTMLQuoteElement", 
    "HTMLScriptElement", 
    "HTMLSelectElement", 
    "HTMLStyleElement", 
    "HTMLTableCaptionElement", 
    "HTMLTableCellElement", 
    "HTMLTableColElement", 
    "HTMLTableElement", 
    "HTMLTableRowElement", 
    "HTMLTableSectionElement", 
    "HTMLTextAreaElement", 
    "HTMLTitleElement", 
    "HTMLUListElement", 
    "Image", 
    "MutationEvent", 
    "Node", 
    "NodeFilter", 
    "Option", 
    "ProcessingInstruction", 
    "Range", 
    "RangeError", 
    "ReferenceError", 
    "SyntaxError", 
    "Text", 
    "TypeError", 
    "URIError", 
    "XMLDocument", 
    "XMLHttpRequest", 
    "XMLSerializer", 
    "XPathEvaluator", 
    "XPathResult", 
    "XSLTProcessor",
    "addEventListener", 
    "alert", 
    "atob", 
    "btoa", 
    "captureEvents",
    "clearInterval", 
    "clearTimeout",
    "clientInformation", 
    "console", 
    "devicePixelRatio", 
    "event", 
    "frames",
    "innerHeight", 
    "innerWidth", 
    "length",
    "locationbar", 
    "menubar", 
    "offscreenBuffering", 
    "opener",
    "outerHeight", 
    "outerWidth", 
    "pageXOffset",
    "pageYOffset",
    "parent",
    "personalbar",
    "screen",
    "screenLeft", 
    "screenTop", 
    "screenX", 
    "screenY", 
    "scrollX", 
    "scrollY", 
    "scrollbars",
    "self",
    "statusbar",
    "toolbar"
];

var windowReadOnlyProperties = [
    "closed",
    "document",
    "history",
    "navigator",
    "window",
    "top"
];

var windowReadWriteStringProperties = [
    "defaultStatus",
    "defaultstatus",
    "name",
    "status"
];

var windowFunctions = [
    "blur",
    "close",
    "confirm",
    "find", 
    "focus",
    "getComputedStyle",
    "getSelection",
    "moveBy", 
    "moveTo", 
    "open", 
    "print", 
    "prompt", 
    "releaseEvents",
    "removeEventListener", 
    "resizeBy", 
    "resizeTo", 
    "scroll", 
    "scrollBy", 
    "scrollTo", 
    "setInterval", 
    "setTimeout", 
    "stop"
];

var windowEventHandlers = [
    "onabort", 
    "onbeforeunload", 
    "onblur", 
    "onchange", 
    "onclick", 
    "ondblclick", 
    "onerror", 
    "onfocus", 
    "onkeydown", 
    "onkeypress", 
    "onkeyup", 
    "onload", 
    "onmousedown", 
    "onmousemove", 
    "onmouseout", 
    "onmouseover", 
    "onmouseup", 
    "onmousewheel", 
    "onreset", 
    "onresize", 
    "onscroll", 
    "onsearch", 
    "onselect", 
    "onsubmit", 
    "onunload"
];

window.onload = function()
{
    if (window.testRunner)
        testRunner.dumpAsText();

    log("\n----- tests for getting/setting read-write properties -----\n");

    for (var i = 0; i < windowReadWriteProperties.length; i++) {
        var property = windowReadWriteProperties[i];
        shouldBeTrue("canGet('" + property + "')");
        shouldBeTrue("canSet('" + property + "')");
    }

    log("\n----- tests for getting/setting readonly properties -----\n");

    for (var i = 0; i < windowReadOnlyProperties.length; i++) {
        var property = windowReadOnlyProperties[i];
        shouldBeTrue("canGet('" + property + "')");
        shouldBeFalse("canSet('" + property + "')");
    }

    log("\n----- tests for getting/setting string properties -----\n");
    for (var i = 0; i < windowReadWriteStringProperties.length; i++) {
        var property = windowReadWriteStringProperties[i];
        shouldBeTrue("canGet('" + property + "')");
        shouldBeTrue("canSetWithTypeConversion('" + property + "')");
        
    }

    log("\n----- tests for getting/setting functions -----\n");

    for (var i = 0; i < windowFunctions.length; i++) {
        var property = windowFunctions[i];
        shouldBeTrue("canGet('" + property + "')");
        shouldBeTrue("canSet('" + property + "')");
    }

    log("\n----- tests for getting/setting event handlers -----\n");

    for (var i = 0; i < windowEventHandlers.length; i++) {
        var property = windowEventHandlers[i];
        shouldBeTrue("canGet('" + property + "')");
        shouldBeTrue("canSetWithCallable('" + property + "')");
    }
}
</script>
